# vim:ts=4:sw=4:noet:
""" Binary image format """

from c.base.support import CoreException

binmsgs = ["<", "<=", "+", "="," -", "new:"]

class CMG:
	def __init__(self, mem):
		self.mem = mem
		self.objhash = {}
		self.img = [0]*0x1000

	def save(self, fn):
		f = file(fn,"wb")
		b = self.saveToBuf()
		f.write(map(chr,b))
		f.close()

	def saveToBuf(self):
		buf = []
		self.buf16(buf, self.mem.nilObject.writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("true").writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("false").writeCMG(self))
		self.buf16(buf, self.mem.getGlobalValues().writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("SmallInt").writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("Integer").writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("Array").writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("Block").writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("Context").writeCMG(self))
		self.buf16(buf, self.mem.getGlobal("Undefined").methods.get("boot").writeCMG(self))
		for msg in binmsgs:
			self.buf16(buf, self.mem.newSymbol(msg).writeCMG(self))
		self.buf16(buf, self.mem.newSymbol("doesNotUnderstand:").writeCMG(self))
		
		for d in self.img[0x1000:]:
			self.buf16(buf,d)
		self.imageSize = 2*(len(self.img)-0x1000)
		return buf

	def buf16(self, buf, v):
		buf.append(v&0xFF)
		buf.append((v>>8)&0xFF)

	def newObject(self,size, bin=False):
		bsize = size
		if not bin:
			bsize*=2
		if bsize>=126:
			raise CoreException("warning: object sized: %s" % size)
		p = len(self.img)
		if bin:
			x = [0]*(2+((size+1)>>1))
			x[0] = size<<2
			x[0] |= (1<<15)
		else:
			x = [0]*(2+size)
			x[0] = size<<2
		self.img.extend(x)
		return p

	def newInteger(self, val):
		if (val<0):
			val = ((-val)^0xFFFF) + 1
		av = (val<<2)|2
		return av
